package my.test.tool;

import com.spring.test.factory.StaticCarFactory;
import org.junit.Test;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver;
import org.springframework.beans.factory.xml.NamespaceHandler;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;

import java.beans.Introspector;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 记录有用的工具类
 */
public class SpringTools {
	/**
	 * 所在模块: spring-core
	 * org.springframework.util.ReflectionUtils
	 */
	@Test
	public void ReflectionUtilsTest(){
		/**
		 step05 => invokeBeanFactoryPostProcessors(beanFactory)
		 */
		/**
		 * 方法声明：
		 * org.springframework.util.ReflectionUtils#getUniqueDeclaredMethods(java.lang.Class, org.springframework.util.ReflectionUtils.MethodFilter)
		 * 源码出现位置：
		 * org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#getTypeForFactoryMethod#798
		 */
		Method[] candidates = ReflectionUtils.getUniqueDeclaredMethods(StaticCarFactory.class, ReflectionUtils.USER_DECLARED_METHODS);
		for (Method candidate : candidates) {
			System.out.println(candidate);
		}
	}



	/**
	 * 所在模块: spring-core
	 * CollectionUtils
	 */
	@Test
	public void collectionUtilsTest() {
		/**
		 方法声明:
		 public static <K, V> void mergePropertiesIntoMap(@Nullable Properties props, Map<K, V> map)
		 源码出现位置:
		 org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver#getHandlerMappings()#180
		 */
		//1.合并properties内容到Map
		Properties prop = new Properties();
		prop.setProperty("title1","content1");
		prop.setProperty("title2","content2");
		Map<String, Object> dest = new ConcurrentHashMap<>();
		CollectionUtils.mergePropertiesIntoMap(prop,dest);
		System.out.println(dest);
	}

	/***************
	 *  反射工具类  *
	 ***************/
	/**
	 * 所在模块: spring-core
	 * ClassUtils
	 */
	@Test
	public void classUtilsTest() throws ClassNotFoundException {
		/**
		    方法声明:
		 	public static Class<?> forName(String name, @Nullable ClassLoader classLoader)
		 	源码出现位置:
		 	org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver#resolve(java.lang.String)#135
		 */
		//加载类
		String className = "org.springframework.context.config.ContextNamespaceHandler";
		Class<?> handlerClass = ClassUtils.forName(className, this.getClass().getClassLoader());
		System.out.println(handlerClass);
		/**
		 	方法声明:
		 	public static String getShortName(String className)
		 	源码出现位置:
		 	org.springframework.context.annotation.AnnotationBeanNameGenerator#buildDefaultBeanName(org.springframework.beans.factory.config.BeanDefinition)#171
		 */
		//根据全类名获取类名首字母小写
		String beanClassName = "com.spring.test.service.impl.OrderServiceImpl";
		String shortClassName = ClassUtils.getShortName(beanClassName);
		System.out.println(Introspector.decapitalize(shortClassName));
	}

	/**
	 * 所在模块: spring-beans
	 * BeanUtils
	 */
	@Test
	public void beanUtilsTest() throws ClassNotFoundException {
		String className = "org.springframework.context.config.ContextNamespaceHandler";
		Class<?> handlerClass = ClassUtils.forName(className, this.getClass().getClassLoader());
		/**
		 	方法声明:
		 	public static <T> T instantiateClass(Class<T> clazz) throws BeanInstantiationException
		 	源码出现位置:
		 	org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver#resolve(java.lang.String)#141
		 */
		//初始化类
		NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass);
		System.out.println(namespaceHandler);
	}


	/***************
	 *  资源加载    *
	 ***************/
	/**
	 * 所在模块: spring-core
	 * PropertiesLoaderUtils
	 */
	@Test
	public void propertiesLoaderUtilsTest() throws IOException {
		/**
		 	方法声明:
		 	public static Properties loadAllProperties(String resourceName, @Nullable ClassLoader classLoader) throws IOException
		 	源码出现位置:
		    org.springframework.beans.factory.xml.PluggableSchemaResolver#getSchemaMappings()#158
		    org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver#getHandlerMappings()#175
		 */
		Properties schemaMappings = PropertiesLoaderUtils.loadAllProperties("META-INF/spring.schemas", this.getClass().getClassLoader());
		System.out.println("schemaMappings的size:"+schemaMappings.size());
		Properties handlerMappings = PropertiesLoaderUtils.loadAllProperties("META-INF/spring.handlers", this.getClass().getClassLoader());
		System.out.println("handlerMappings的size:"+handlerMappings.size());
	}

	/***************
	 *  字符串处理  *
	 ***************/
	/**
	 * 所在模块: spring-core
	 * StringUtils
	 */
	@Test
	public void StringUtilsTest(){
		/**
		 方法声明:
		 org.springframework.util.StringUtils#tokenizeToStringArray(java.lang.String, java.lang.String)
		 源码出现位置:
		 org.springframework.context.annotation.ComponentScanBeanDefinitionParser#parse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext)#88
		 */
		//字符串分割
		System.out.println("========tokenizeToStringArray========");
		String basePackage = "test1,test2;test3";
		String[] basePackages = StringUtils.tokenizeToStringArray(basePackage,
				ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
		for (String pack : basePackages) {
			System.out.print(pack+" ");
		}
		System.out.println();
		/**
		 方法声明:
		 org.springframework.util.StringUtils#replace(java.lang.String, java.lang.String, java.lang.String)
		 源码出现位置:
		 org.springframework.core.io.support.PathMatchingResourcePatternResolver#retrieveMatchingFiles(java.io.File, java.lang.String)#778
		 */
		//字符串替换
		System.out.println("========replace========");
		String url = "D:\\dev\\workspace\\";
		String fullPattern = StringUtils.replace(url, File.separator, "/");
		System.out.print(fullPattern);
	}

}
